package com.weaving.monitor.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.weaving.monitor.entity.RedisMachineData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * Redis服务类
 * 
 * 功能说明：
 * 1. 从Redis获取机器实时状态数据
 * 2. 支持获取指定机器号的实时数据
 * 3. 处理Redis连接异常和数据解析异常
 * 
 * @author 系统开发团队
 * @version 1.0
 * @since 2024-01-01
 */
@Service
@Slf4j
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 从Redis获取指定机器的实时数据
     * 
     * @param machineNumber 机器号（如：1, 2, 3...）
     * @return Redis机器数据，如果不存在或解析失败则返回null
     */
    public RedisMachineData getMachineData(Integer machineNumber) {
        try {
            // 构建Redis key，格式：knitting_snapshot_J001
            String key = String.format("knitting_snapshot_J%03d", machineNumber);
            
            log.debug("从Redis获取机器数据，key: {}", key);
            
            // 从Redis获取数据
            Object value = redisTemplate.opsForValue().get(key);
            
            if (value == null) {
                log.warn("Redis中不存在机器 {} 的数据", machineNumber);
                return null;
            }
            
            // 处理不同的数据类型
            if (value instanceof RedisMachineData) {
                return (RedisMachineData) value;
            } else if (value instanceof String) {
                // 如果是JSON字符串，直接解析
                return objectMapper.readValue((String) value, RedisMachineData.class);
            } else {
                // 尝试将Object转换为Map再处理
                try {
                    @SuppressWarnings("unchecked")
                    java.util.Map<String, Object> map = (java.util.Map<String, Object>) value;
                    return convertMapToRedisMachineData(map);
                } catch (Exception e) {
                    log.error("转换Redis数据为Map失败", e);
                    return null;
                }
            }
            
        } catch (Exception e) {
            log.error("从Redis获取机器 {} 数据时发生异常", machineNumber, e);
            return null;
        }
    }
    
    /**
     * 将Map转换为RedisMachineData对象
     */
    private RedisMachineData convertMapToRedisMachineData(java.util.Map<String, Object> map) {
        RedisMachineData data = new RedisMachineData();
        
        try {
            // 使用反射设置字段值
            java.lang.reflect.Field[] fields = RedisMachineData.class.getDeclaredFields();
            for (java.lang.reflect.Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                
                if (map.containsKey(fieldName)) {
                    Object value = map.get(fieldName);
                    if (value != null) {
                        // 处理不同类型的转换
                        if (field.getType() == Integer.class && value instanceof Number) {
                            field.set(data, ((Number) value).intValue());
                        } else if (field.getType() == Double.class && value instanceof Number) {
                            field.set(data, ((Number) value).doubleValue());
                        } else if (field.getType() == String.class) {
                            field.set(data, value.toString());
                        } else if (field.getType() == java.util.List.class && value instanceof java.util.List) {
                            field.set(data, value);
                        } else {
                            field.set(data, value);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("转换Map到RedisMachineData失败", e);
        }
        
        return data;
    }

    /**
     * 检查Redis连接是否正常
     * 
     * @return true-连接正常，false-连接异常
     */
    public boolean isRedisConnected() {
        try {
            redisTemplate.getConnectionFactory().getConnection().ping();
            return true;
        } catch (Exception e) {
            log.error("Redis连接检查失败", e);
            return false;
        }
    }

    /**
     * 获取Redis中所有机器数据的key列表
     * 
     * @return 机器数据key列表
     */
    public java.util.Set<String> getAllMachineKeys() {
        try {
            return redisTemplate.keys("knitting_snapshot_J*");
        } catch (Exception e) {
            log.error("获取Redis机器数据key列表失败", e);
            return java.util.Collections.emptySet();
        }
    }
} 